/*!
 * \file http_comm.c
 *
 * \brief http comm 函数
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 *
 * \version 3.0
 * \author geyh
 * \date 2016/01/28
 *
 */
#include <sys/time.h>

#include "frsoap_parse.h"
#include "iconv2utf8.h"
#include "frgzip_decompress.h"
#include "frbase64.h"
#include "http_comm.h"
#include "../http1/http_chunk.h"
#include "../extend/http_bodydata_deal.h"

extern int g_i_redetect;
extern int g_i_report_non_xml_json_html;
extern int g_i_rmi;
extern int g_i_hessian;

/*******************************************************************************
*  FUNC     :  创建L7session_http_private
*  ARGS     :  void
*  RTN      :  NULL                         (失败)
*           :  p_st_http_private            (成功)
*  NOTE     :
*******************************************************************************/
L7session_http_private* http_private_create(void)
{
    L7session_http_private *p_st_http_private = NULL;

    //申请内存并初始化
    p_st_http_private = (L7session_http_private *)frmalloc(sizeof(L7session_http_private));
    if(p_st_http_private == NULL)
        return NULL;

    memset(p_st_http_private,'\0',sizeof(L7session_http_private));

    //stream ID  31bit 正数

    p_st_http_private->u32_current_resp_id = 0x80000000;

    return p_st_http_private;
}

FR_STATIC Http_comm_session* __http_comm_session_create(void)
{
    Http_comm_session *p_comm_session = NULL;

    p_comm_session = (Http_comm_session *)frmalloc(sizeof(Http_comm_session));
    if (p_comm_session == NULL)
        return NULL;

    memset(p_comm_session, 0x00, sizeof(Http_comm_session));

    p_comm_session->p_st_data = bytebuff_creat();
    if(p_comm_session->p_st_data == NULL)
    {
        frfree(p_comm_session);
        return NULL;
    }

    p_comm_session->i_flag_redetect = g_i_redetect;

    return p_comm_session;
}

FR_STATIC void __http_comm_session_destroy(Http_comm_session **pp_comm_session)
{
    Http_comm_session *p_comm_session = NULL;

    if(pp_comm_session == NULL)
        return;

    p_comm_session = *pp_comm_session;

    if(p_comm_session)
    {
        if(p_comm_session->p_st_data)
            bytebuff_free(&p_comm_session->p_st_data);

        if(p_comm_session->p_boundary)
            frfree(p_comm_session->p_boundary);

        if(p_comm_session->p_code_string)
            frfree(p_comm_session->p_code_string);

        if(p_comm_session->p_err_msg)
            frfree(p_comm_session->p_err_msg);

        if(p_comm_session->p_uri)
            frfree(p_comm_session->p_uri);

        if(p_comm_session->p_xml_data)
            frfree(p_comm_session->p_xml_data);

        if(p_comm_session->p_lst_req_tmp)
            frreport_body_l7list_free(&p_comm_session->p_lst_req_tmp);

        //p_lst_comm_tmp
        if(p_comm_session->p_lst_comm_tmp)
            frreport_body_l7list_free(&p_comm_session->p_lst_comm_tmp);

        if(p_comm_session->p_st_body_data_req)
            frreport_body_free(&p_comm_session->p_st_body_data_req);

        if(p_comm_session->p_st_body_data_resp)
            frreport_body_free(&p_comm_session->p_st_body_data_resp);

        frfree(p_comm_session);
    }

    *pp_comm_session = NULL;
    return;
}

Http1_session* http1_session_create(void)
{
    Http1_session *p_http1_session = NULL;

    p_http1_session = (Http1_session *)frmalloc(sizeof(Http1_session));
    if(p_http1_session == NULL)
        return NULL;

    memset(p_http1_session, 0x00, sizeof(Http1_session));

    p_http1_session->p_st_comm_session = __http_comm_session_create();
    if(p_http1_session->p_st_comm_session == NULL)
    {
        frfree(p_http1_session);
        return NULL;
    }

    return p_http1_session;
}

void http1_session_destroy(Http1_session **pp_http1_session)
{
    Http1_session *p_http1_session = NULL;

    if(pp_http1_session == NULL)
        return;

    p_http1_session = *pp_http1_session;

    if(p_http1_session)
    {
        __http_comm_session_destroy(&p_http1_session->p_st_comm_session);
        frfree(p_http1_session);
    }

    *pp_http1_session = NULL;
    return;
}

Http2_session* http2_session_create(void)
{
    Http2_session *p_http2_session = NULL;

    p_http2_session = (Http2_session *)frmalloc(sizeof(Http2_session));
    if(p_http2_session == NULL)
        return NULL;

    memset(p_http2_session, 0x00, sizeof(Http2_session));

    p_http2_session->u32_stream_id = 0x80000000;
    p_http2_session->u8_type = 0xff;

    p_http2_session->p_st_comm_session = __http_comm_session_create();
    if(p_http2_session->p_st_comm_session == NULL)
    {
        frfree(p_http2_session);
        return NULL;
    }

    return p_http2_session;
}

void http2_session_destroy(Http2_session **pp_http2_session)
{
    Http2_session *p_http2_session = NULL;

    if(pp_http2_session == NULL)
        return;

    p_http2_session = *pp_http2_session;

    if(p_http2_session)
    {
        __http_comm_session_destroy(&p_http2_session->p_st_comm_session);

        if(p_http2_session->p_title)
            frfree(p_http2_session->p_title);

        frfree(p_http2_session);
    }

    *pp_http2_session = NULL;
    return;
}


//判断字段是否上报
int http_field_name_filter(char *p_field_name)
{
    if(p_field_name == NULL)
        return FR_FAIL;

    if(strcasecmp(p_field_name, "content-length") == 0)
        return FR_FAIL;
    else if(strcasecmp(p_field_name, "www-authenticate") == 0)
        return FR_FAIL;
    else if(strcasecmp(p_field_name, "proxy-authenticate") == 0)
        return FR_FAIL;
    else if(strcasecmp(p_field_name, "content-md5") == 0)
        return FR_FAIL;
//    else if
//    {
//        //todo
//    }
    return FR_SUCC;
}

/*
 * 判断body体里面的内容是否上报
 *
 * \ret                 FR_SUCC
 *                      FR_FAIL
 *
 */
int http_data_type_detect(char *p_field_value, Http_comm_session *p_comm_session)
{
    if(p_field_value == NULL || p_comm_session == NULL)
        return FR_FAIL;

    if(strcasestr(p_field_value, "xml"))
    {
        p_comm_session->i_flag_need = 1;
        p_comm_session->i_flag_data_type = HTTP_XML_DATA;
        return FR_SUCC;
    }
    else if(strcasestr(p_field_value, "json"))
    {
        p_comm_session->i_flag_need = 1;
        p_comm_session->i_flag_data_type = HTTP_JSON_DATA;
        return FR_SUCC;
    }
    else if(strcasestr(p_field_value,"text/") != NULL)
    {
        p_comm_session->i_flag_data_type = HTTP_TEXT_DATA;
        p_comm_session->i_flag_need = 1;
        return FR_SUCC;
    }
    else if(strcasestr(p_field_value, "html"))
    {
        p_comm_session->i_flag_need = 2;
        p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
        return FR_SUCC;
    }
    else if(strcasestr(p_field_value, "hessian"))
    {
        if(g_i_hessian)
        {
            p_comm_session->i_flag_data_type = HTTP_HESSIAN_DATA;
            p_comm_session->i_flag_need = 1;
            return FR_SUCC;
        }
    }
    
    switch (p_field_value[0])
    {
        case 'a':
            //application
            if(strstr(p_field_value, "application/x-www-form-urlencoded"))
                p_comm_session->i_flag_need = 1;
            else if(strcasestr(p_field_value, "application/"))
            {
                //如果是x-java-serialized-object 直接返回 根据body体来判断
                if(strcasestr(p_field_value, "application/x-java-serialized-object"))
                {
                    if (g_i_rmi)
                        p_comm_session->i_flag_need = 0;
                    else
                        p_comm_session->i_flag_need = 2;
                }
                else
                    p_comm_session->i_flag_need = 2;
    
                return FR_SUCC;
            }
            else if(strcasestr(p_field_value, "audio/"))
                p_comm_session->i_flag_need = 2;

            break;

        case 'd':
            if(strcasestr(p_field_value, "drawing/"))
                p_comm_session->i_flag_need = 2;

            break;

        case 'i':
            if(strcasestr(p_field_value, "image/"))
                p_comm_session->i_flag_need = 2;

            break;

        case 'j':
            if(strcasestr(p_field_value, "java/"))
                p_comm_session->i_flag_need = 2;

            break;

        case 'm':
            if(strcasestr(p_field_value, "message/"))
                p_comm_session->i_flag_need = 2;
            else if(strcasestr(p_field_value, "multipart/form-data"))
            {
                p_comm_session->i_flag_data_type = HTTP_FORM_DATA;
                p_comm_session->i_flag_need = 1;
            }

            break;

        case 'v':
            if(strcasestr(p_field_value, "video/"))
                p_comm_session->i_flag_need = 2;

            break;

        case 'M':
            if(strcasestr(p_field_value, "Model/"))
                p_comm_session->i_flag_need = 2;

            break;

        default:
            break;
    }
    
    if(p_comm_session->i_flag_need == 0)
    {
        if (g_i_report_non_xml_json_html)
            p_comm_session->i_flag_need = 1;
        else
            p_comm_session->i_flag_need = 2;
    }

    return FR_SUCC;

}


int http_suffixdetect(char *p_uri, Http_comm_session *p_comm_session)
{
    char *p_pos = NULL;

    if(p_uri == NULL || p_comm_session == NULL)
        return FR_FAIL;

    if(p_comm_session->i_flag_need != 0)
        return FR_SUCC;

    p_pos = strrchr(p_uri, '.');
    if(p_pos == NULL)
        return FR_FAIL;

    p_pos++;

    switch (p_pos[0])
    {
        case '3':
            if(strcasecmp(p_pos, "323") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'a':
        case 'A':
            if (strcasecmp(p_pos, "asa") == 0 || strcasecmp(p_pos, "asp") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'b':
        case 'B':
            if(strcasecmp(p_pos, "biz") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'c':
        case 'C':
            if(strcasecmp(p_pos, "cml") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'd':
        case 'D':
            if(strcasecmp(p_pos, "dcd") == 0 || strcasecmp(p_pos, "dtd") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'e':
        case 'E':
            if(strcasecmp(p_pos, "ent") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'f':
        case 'F':
            if(strcasecmp(p_pos, "fo") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'm':
        case 'M':
            if(strcasecmp(p_pos, "math") == 0 || strcasecmp(p_pos, "mml") == 0
                    || strcasecmp(p_pos, "mtx") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'o':
        case 'O':
            if(strcasecmp(p_pos, "odc") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'r':
        case 'R':
            if(strcasecmp(p_pos, "rdf") == 0 )
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else if(strcasecmp(p_pos, "r3t") == 0 || strcasecmp(p_pos, "rt") == 0 )
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 's':
        case 'S':
            if(strcasecmp(p_pos, "sol") == 0 || strcasecmp(p_pos, "sor") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else if(strcasecmp(p_pos, "svg") == 0 || strcasecmp(p_pos, "spp") == 0 )
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 't':
        case 'T':
            if(strcasecmp(p_pos, "txt") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else if(strcasecmp(p_pos, "tld") == 0 || strcasecmp(p_pos, "tsd") == 0 )
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'u':
        case 'U':
            if(strcasecmp(p_pos, "uls") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'v':
        case 'V':
            if(strcasecmp(p_pos, "vcf") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else if(strcasecmp(p_pos, "vml") == 0 || strcasecmp(p_pos, "vxml") == 0 )
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'w':
        case 'W':
            if(strcasecmp(p_pos, "wml") == 0 || strcasecmp(p_pos, "wsc") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_OTHERS_DATA;
            }
            else if(strcasecmp(p_pos, "wsdl") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;

        case 'x':
        case 'X':
            if(strcasecmp(p_pos, "xdr") == 0 || strcasecmp(p_pos, "xml") == 0
                    || strcasecmp(p_pos, "xq") == 0 || strcasecmp(p_pos, "xql") == 0
                    || strcasecmp(p_pos, "xquery") == 0 || strcasecmp(p_pos, "xsd") == 0
                    || strcasecmp(p_pos, "xsl") == 0 || strcasecmp(p_pos, "xslt") == 0)
            {
                p_comm_session->i_flag_need = 1;
                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
            }
            else
            {
                p_comm_session->i_flag_need = 2;
            }

            return FR_SUCC;


        default:
            p_comm_session->i_flag_need = 2;
            return FR_SUCC;
    }
}
/*!
 * http 认证信息解析
 *
 * \p_st_body_data           (上报链表)
 * \p_data_in                (入力数据)
 * \p_st_private             (私有数据)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int http_auth_parse(Frreport_body_data *p_st_body_data, char *p_data_in, L7session_http_private *p_st_private)
{
    char *p_pos = NULL;
    char *p_value = NULL;
    int i_data_out = 0;
    L4_transaction *p_st_l4_trans = NULL;
    Http1_session *p_http1_session = NULL;
    Http2_session *p_http2_session = NULL;
    Http_comm_session *p_comm_session = NULL;

    if(p_st_body_data == NULL || p_data_in == NULL || p_st_private == NULL)
        return FR_FAIL;

    if(p_st_private->i_version == 1)
    {
        p_http1_session = p_st_private->p_http1_sess;
        p_comm_session = p_http1_session->p_st_comm_session;
    }
    else
    {
        p_http2_session = p_st_private->p_http2_sess;
        p_comm_session = p_http2_session->p_st_comm_session;
    }

    p_st_l4_trans = &(p_comm_session->st_l4_trans);

    p_st_private->st_login_timestamp.tv_sec = p_st_l4_trans->st_request_time_first_byte.tv_sec;
    p_st_private->st_login_timestamp.tv_usec = p_st_l4_trans->st_request_time_first_byte.tv_usec;

    fruuid(p_st_private->arr_session_id);

    if(strncasecmp(p_data_in, "Basic", 5) == 0)
    {
        //指向用户名密码
        p_data_in += 6;

        //跳过可能存在的空格
        while(*p_data_in == ' ')
            p_data_in++;

        //解密
        p_value = (char *)frbase64_decode(p_data_in, &i_data_out);
        if(p_value == NULL || i_data_out == 0)
            return FR_FAIL;

        p_pos = strchr(p_value, ':');
        if(p_pos == NULL)
        {
            frfree(p_value);
            return FR_FAIL;
        }

        *p_pos = '\0';

        if(p_st_private->p_user_name)
            frfree(p_st_private->p_user_name);
        p_st_private->p_user_name = frstrdup((const char *)p_value);
        frfree(p_value);
        if(p_st_private->p_user_name == NULL)
            return FR_FAIL;

        return FR_SUCC;

    }
    else if(strncasecmp(p_data_in, "Digest", 6) == 0 || strncasecmp(p_data_in, "WSSE", 4) == 0)
    {
        //username="admin"  格式
        p_pos = strstr(p_data_in, "username=");
        if(p_pos == NULL)
            return FR_FAIL;

        //跳过引号
        p_pos = strchr(p_pos, '\"');
        if(p_pos == NULL)
            return FR_FAIL;
        p_data_in = p_pos + 1;

        //查找下一个引号
        p_pos = strchr(p_data_in, '\"');
        if(p_pos == NULL)
            return FR_FAIL;

        *p_pos = '\0';

        //删除原来的用户名
        if(p_st_private->p_user_name)
            frfree (p_st_private->p_user_name);

        p_st_private->p_user_name = frstrdup((const char *)p_data_in);
        if(p_st_private->p_user_name == NULL)
            return FR_FAIL;
    }

    return FR_SUCC;
}

/*
    url  decoding
    url=www.baidu.com&params%5B0%5D%5Bname%5D=name&params%5B0%5D%5Bvalue%5D=zxd&params%5B0%5D%5Bmethod%5D=get
    %5B0
*/

int http_url_decode(char *p_src, int i_data_len, char **pp_dst)
{
    char *p_out = NULL, *p_tmp = NULL, *p_pos = NULL;
    char c_tmp;
    int i_tmp = 0;

    if(p_src == NULL || pp_dst == NULL || i_data_len <= 0)
        return FR_FAIL;

    p_out = (char *)frmalloc(i_data_len + 1);
    if(p_out == NULL)
        return FR_FAIL;

    //最后输出
    p_tmp = p_src;
    p_pos = p_out;

    // %5b 转换为0x5b 并将字符串前移两位
    while(i_data_len > 0)
    {
        if(*p_tmp == '%')
        {
            //字符串转为字符
            //snprintf(arr_tmp, sizeof(arr_tmp), "%s", p_tmp + 1);
            if(i_tmp)
            {
                memcpy(p_pos, p_tmp - i_tmp, i_tmp);
                p_pos+=i_tmp;
                i_tmp = 0;
            }

            if(*(p_tmp + 1) >= '0' && *(p_tmp + 1) <= '9')
                c_tmp = 16 * (*(p_tmp + 1) - 48);
            else if(*(p_tmp + 1) >= 'A' && *(p_tmp + 1) <= 'F')
                c_tmp = 16 * (*(p_tmp + 1) - 55);
            else if(*(p_tmp + 1) >= 'a' && *(p_tmp + 1) <= 'f')
                c_tmp = 16 * (*(p_tmp + 1) - 87);
            else
            {
                frfree(p_out);
                return FR_FAIL;
            }

            if(*(p_tmp + 2) >= '0' && *(p_tmp + 2) <= '9')
                c_tmp += (*(p_tmp + 2) - 48);
            else if(*(p_tmp + 2) >= 'A' && *(p_tmp + 2) <= 'F')
                c_tmp += (*(p_tmp + 2) - 55);
            else if(*(p_tmp + 2) >= 'a' && *(p_tmp + 2) <= 'f')
                c_tmp += (*(p_tmp + 2) - 87);
            else
            {
                frfree(p_out);
                return FR_FAIL;
            }

            *p_pos = c_tmp;
            p_pos++;
            p_tmp+=3;
            i_data_len-=3;
        }
        else
        {
            i_tmp++;
            p_tmp++;
            i_data_len--;
        }
    }

    if(i_tmp)
    {
        memcpy(p_pos, p_tmp - i_tmp, i_tmp);
        p_pos+=i_tmp;
    }
    //最后一位赋0
    *p_pos = '\0';

    *pp_dst = p_out;
    return FR_SUCC;

}




/*
*   http session 数据上报
*/
int http_session_report(Frreport_body_data *p_st_body_data, L7session_http_private *p_st_private)
{
    if(p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    if(frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_SESSION_USERNAME, p_st_private->p_user_name) == FR_FAIL)
        return FR_FAIL;

    if(frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_SESSION_ID, p_st_private->arr_session_id) == FR_FAIL)
        return FR_FAIL;

    if(frreport_body_l7_add_timeval(p_st_body_data, APM_REPORT_KEY_SESSION_LOGIN_TIMESTAMP, &p_st_private->st_login_timestamp) == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*!
 * 判断multipart数据是否结束
 *
 * \pp_tcp_body              (入力数据)
 * \p_ui_tcp_body_len        (入力数据长度)
 * \p_st_private             (私有数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败数据格式内容有误\n
 *         APM_L7_ANALYZE_TODO:multipart 分割符 另一块数据开头\n
 *         APM_L7_ANALYZE_SUCC:multipart 所有数据结束\n
 *
 */
int multipart_data_end(char **pp_tcp_body, unsigned int *p_ui_tcp_body_len, L7session_http_private *p_st_private)
{
    unsigned int ui_data_len = 0;
    char *p_tcp_body = NULL;
    unsigned int ui_boundary_len = 0;
    Http1_session *p_http1_session = NULL;
    Http2_session *p_http2_session = NULL;
    Http_comm_session *p_comm_session = NULL;

    if(pp_tcp_body == NULL || *pp_tcp_body == NULL || p_ui_tcp_body_len == NULL || p_st_private == NULL)
        return APM_L7_ANALYZE_FAIL;

    p_tcp_body = *pp_tcp_body;
    ui_data_len = *p_ui_tcp_body_len;

    if(ui_data_len < 2)
        return APM_L7_ANALYZE_FAIL;

    if(*p_tcp_body != '-' || p_tcp_body[1] != '-')
        return APM_L7_ANALYZE_FAIL;

    p_tcp_body += 2;
    ui_data_len -= 2;

    if(p_st_private->i_version == 1)
    {
        p_http1_session = p_st_private->p_http1_sess;
        p_comm_session = p_http1_session->p_st_comm_session;
    }
    else
    {
        p_http2_session = p_st_private->p_http2_sess;
        p_comm_session = p_http2_session->p_st_comm_session;
    }

    ui_boundary_len = strlen(p_comm_session->p_boundary);

    if(ui_data_len < ui_boundary_len)
        return APM_L7_ANALYZE_FAIL;

    if(strncmp(p_tcp_body, p_comm_session->p_boundary, ui_boundary_len) != 0)
        return APM_L7_ANALYZE_FAIL;

    p_tcp_body += ui_boundary_len;
    ui_data_len -= ui_boundary_len;

    // \r\n
    if(p_tcp_body[0] == '-' && p_tcp_body[1] == '-')
    {
        *pp_tcp_body = p_tcp_body + 4;
        *p_ui_tcp_body_len = ui_data_len - 4;
        return APM_L7_ANALYZE_SUCC;
    }

    *pp_tcp_body = p_tcp_body + 2;
    *p_ui_tcp_body_len = ui_data_len - 2;
    return APM_L7_ANALYZE_TODO;

}


/*!
 * http 认证信息解析
 *
 * \p_tcp_body                  (入力数据)
 * \ui_tcp_body_len             (入力数据长度)
 * \p_st_body_data              (上报链表)
 * \p_st_private                (私有数据)
 * \i_use_request               (是否是request数据)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int multipart_data_parse(char *p_tcp_body, unsigned int ui_tcp_body_len, Frreport_body_data *p_st_body_data, L7session_http_private *p_st_private, int i_use_request)
{
    int i_ret = 0;
    int i_content_index = 0;
    char *p_pos = NULL, *p_field_name = NULL, *p_field_value = NULL;
    char *p_field_name_tmp = NULL, *p_field_value_tmp = NULL;
    unsigned int ui_name_len = 0, ui_value_len = 0, ui_data_len = 0;
    char arr_body_name[64], arr_charset[16];
    int i_flag_xml = 0;
    Http1_session *p_http1_session = NULL;
    Http2_session *p_http2_session = NULL;
    Http_comm_session *p_comm_session = NULL;
    char *p_form_name = NULL;
    int i_flag_need = 2;

    if(p_tcp_body == NULL || ui_tcp_body_len == 0 || p_st_body_data == NULL || p_st_private == NULL)
        return APM_L7_ANALYZE_FAIL;

    i_ret = multipart_data_end(&p_tcp_body, &ui_tcp_body_len, p_st_private);
    if(i_ret == APM_L7_ANALYZE_FAIL)
        return APM_L7_ANALYZE_FAIL;

    if(p_st_private->i_version == 1)
    {
        p_http1_session = p_st_private->p_http1_sess;
        p_comm_session = p_http1_session->p_st_comm_session;
    }
    else
    {
        p_http2_session = p_st_private->p_http2_sess;
        p_comm_session = p_http2_session->p_st_comm_session;
    }

    while(i_ret != APM_L7_ANALYZE_SUCC)
    {
        i_flag_need = 0;

        i_content_index ++;
        //单个http 头信息解析
        while(strncmp(p_tcp_body, "\r\n", 2) != 0)
        {
            //单个数据段解析
            //name
            p_pos = strchr(p_tcp_body, ':');
            if(p_pos == NULL)
                return APM_L7_ANALYZE_FAIL;

            ui_name_len = p_pos - p_tcp_body;
            p_field_name = (char *)frmalloc(ui_name_len + 1);
            if(p_field_name == NULL)
                return APM_L7_ANALYZE_FAIL;

            snprintf(p_field_name, ui_name_len + 1, "%s", p_tcp_body);
            frtrim(p_field_name);
            p_tcp_body = p_pos + 1;
            ui_tcp_body_len -= ui_name_len + 1;
            //value
            p_pos = strstr(p_tcp_body, "\r\n");
            if(p_pos == NULL)
            {
                frfree(p_field_name);
                return APM_L7_ANALYZE_FAIL;
            }

            ui_value_len = p_pos - p_tcp_body;
            p_field_value = (char *)frmalloc(ui_value_len + 1);
            if(p_field_value == NULL)
            {
                frfree(p_field_name);
                return APM_L7_ANALYZE_FAIL;
            }

            snprintf(p_field_value, ui_value_len + 1, "%s", p_tcp_body);
            frtrim(p_field_value);
            p_tcp_body = p_pos + 2;
            ui_tcp_body_len -= ui_value_len + 2;

            //判断该数据是否上报
            if(p_comm_session->i_flag_data_type == HTTP_FORM_DATA)
            {
                if(strcasecmp(p_field_name, "Content-Disposition") == 0)
                {
                    //获取 form name=
                    p_pos = strstr(p_field_value, "name=");
                    if(p_pos)
                    {
                        p_pos = strchr(p_pos, '"');
                        if(p_pos)
                        {
                            p_pos++;
                            p_form_name = frstrdup(p_pos);
                            p_pos = strchr(p_form_name, '"');
                            if(p_pos)
                                *p_pos = '\0';
                        }
                    }

                }
            }

            if(strcasecmp(p_field_name, "Content-Type") == 0)
            {
                //获取charset
                p_pos = strstr(p_field_value, "charset=");
                if(p_pos == NULL)
                {
                    snprintf(arr_charset, sizeof(arr_charset), "%s", "utf-8");
                }
                else
                {
                    //指向内容
                    p_pos += 8;
                    snprintf(arr_charset, sizeof(arr_charset), "%s", p_pos);
                    p_pos = strchr(p_comm_session->arr_charset, ';');
                    if(p_pos)
                        *p_pos = '\0';

                    frtrim(arr_charset);
                }
                i_flag_xml = 0;


                if(strcasestr(p_field_value,"xml") != NULL)
                {
                    p_comm_session->i_flag_data_type = HTTP_XML_DATA;
                    i_flag_need = 1;
                }
                else if(strcasestr(p_field_value,"json") != NULL)
                {
                    p_comm_session->i_flag_data_type = HTTP_JSON_DATA;
                    i_flag_need = 1;
                }
                else if(strcasestr(p_field_value,"text/") != NULL)
                {
                    p_comm_session->i_flag_data_type = HTTP_TEXT_DATA;
                    i_flag_need = 1;
                }
                else if(strcasestr(p_field_value,"application/x-www-form-urlencoded") != NULL)
                {
                    p_comm_session->i_flag_data_type = HTTP_UNSET_DATA;
                    i_flag_need = 1;
                    p_comm_session->i_url_encoded = 1;
                }
                else
                {
                    p_comm_session->i_flag_data_type = HTTP_UNSET_DATA;
                    i_flag_need = 2;
                }

            }
            else if(strcasecmp(p_field_name, "Content-Length") == 0)
            {
//                ui_data_len = atoi(p_field_value);
                frfree(p_field_name);
                frfree(p_field_value);
                continue;
            }

            if(i_use_request)
            {
                ui_name_len = strlen(p_field_name) + strlen("request.http.header.") + 5;
                p_field_name_tmp = (char *)frmalloc(ui_name_len);
                if(p_field_name_tmp == NULL)
                {
                    frfree(p_field_name);
                    frfree(p_field_value);
                    return APM_L7_ANALYZE_FAIL;
                }

                snprintf(p_field_name_tmp, ui_name_len, "request.http.header.%s.%d", p_field_name, i_content_index);
                frfree(p_field_name);
                p_field_name = p_field_name_tmp;
                p_field_name_tmp = NULL;
            }
            else
            {
                ui_name_len = strlen(p_field_name) + strlen("response.http.header.") + 5;
                p_field_name_tmp = (char *)frmalloc(ui_name_len);
                if(p_field_name_tmp == NULL)
                {
                    frfree(p_field_name);
                    frfree(p_field_value);
                    return APM_L7_ANALYZE_FAIL;
                }

                snprintf(p_field_name_tmp, ui_name_len, "response.http.header.%s.%d", p_field_name, i_content_index);
                frfree(p_field_name);
                p_field_name = p_field_name_tmp;
                p_field_name_tmp = NULL;
            }

            i_ret = frreport_body_l7_add_str(p_st_body_data, p_field_name, p_field_value);
            frfree(p_field_name);
            frfree(p_field_value);
            if(i_ret == FR_FAIL)
                return APM_L7_ANALYZE_FAIL;

        }

        //  \r\n
        if(ui_tcp_body_len < 2)
            return APM_L7_ANALYZE_FAIL;

        p_tcp_body += 2;
        ui_tcp_body_len -= 2;

        //boundary 之前还有"--"
        p_pos = strstr (p_tcp_body, p_comm_session->p_boundary);
        if(p_pos == NULL)
        {
            if(p_form_name)
                frfree(p_form_name);

            return APM_L7_ANALYZE_FAIL;
        }

        ui_data_len = p_pos - p_tcp_body - 2;


        if(ui_tcp_body_len < (unsigned int)(ui_data_len + 2))
            return APM_L7_ANALYZE_FAIL;

        if(i_flag_need == 1 || (p_form_name && i_flag_need == 0))
        {
            p_field_value = (char *)frmalloc(ui_data_len + 1);
            if(p_field_value == NULL)
            {
                if(p_form_name)
                    frfree(p_form_name);
                return APM_L7_ANALYZE_FAIL;
            }

            snprintf(p_field_value, ui_data_len + 1, "%s", p_tcp_body);

            if(i_flag_xml)
            {
                if(i_use_request)
                    i_ret = frsoap_parse_req(p_field_value, ui_data_len, p_st_body_data);
                else
                    i_ret = frsoap_parse_resp(p_field_value, ui_data_len, p_st_body_data, &p_comm_session->p_code_string, &p_comm_session->p_err_msg);
                if(i_ret == FR_FAIL)
                {
                    if(p_form_name)
                        frfree(p_form_name);

                    frfree(p_field_value);
                    return APM_L7_ANALYZE_FAIL;
                }
            }

            if(i_use_request)
                snprintf(arr_body_name, sizeof(arr_body_name), "request.http.body.%d", i_content_index);
            else
                snprintf(arr_body_name, sizeof(arr_body_name), "response.http.body.%d", i_content_index);
    
            if(p_comm_session->i_flag_need == 1 && p_comm_session->arr_charset[0]!= '\0'
               && (strcasecmp(p_comm_session->arr_charset, "utf-8") != 0 && strcasecmp(p_comm_session->arr_charset, "utf8") != 0))
            {
                i_ret = iconv_to_utf8(p_field_value, ui_data_len, arr_charset, &p_field_value_tmp, &ui_value_len);
                if(i_ret != 0)
                {
                    if(p_form_name)
                        frfree(p_form_name);

                    if(p_field_name_tmp)
                        frfree(p_field_value_tmp);

                    frfree(p_field_value);
                    return APM_L7_ANALYZE_FAIL;
                }

                frfree(p_field_value);
                p_field_value = p_field_value_tmp;
                p_field_value_tmp = NULL;
            }

            if(p_form_name)
            {
                //去除换行
                p_field_value_tmp = (char *)frmalloc(ui_data_len + strlen(p_form_name));
                if(p_field_value_tmp == NULL)
                {
                    frfree(p_field_value);
                    frfree(p_form_name);
                    return APM_L7_ANALYZE_FAIL;
                }

                snprintf(p_field_value_tmp, ui_data_len + strlen(p_form_name), "%s=%s", p_form_name, p_field_value);
                frfree(p_field_value);
                p_field_value = p_field_value_tmp;
                p_field_value_tmp = NULL;
                frfree(p_form_name);
                p_form_name = NULL;
            }

            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_body_name, p_field_value);
            frfree(p_field_value);
            if(i_ret == FR_FAIL)
                return APM_L7_ANALYZE_FAIL;

        }
        else if(i_flag_need == 0)
        {
            //判断是否为xml数据
            if(frxml_detect(p_tcp_body, ui_tcp_body_len) == FR_FAIL)
            {
                ui_value_len = ui_data_len + strlen("<?xml version='1.0' encoding='UTF-8'?>\n");
                p_field_value = (char *)frmalloc(ui_value_len + 1);
                if(p_field_value == NULL)
                    return APM_L7_ANALYZE_FAIL;

                snprintf(p_field_value, ui_value_len + 1, "<?xml version='1.0' encoding='UTF-8'?>\n%s", p_tcp_body);

            }
            else
            {
                p_field_value = (char *)frmalloc(ui_data_len + 1);
                if(p_field_value == NULL)
                    return APM_L7_ANALYZE_FAIL;

                snprintf(p_field_value, ui_data_len + 1, "%s", p_tcp_body);
                ui_value_len = ui_data_len;
            }

            //soap 尝试解析
            if(i_use_request)
                i_ret = frsoap_parse_req(p_field_value, ui_value_len, p_st_body_data);
            else
                i_ret = frsoap_parse_resp(p_field_value, ui_value_len, p_st_body_data, &p_comm_session->p_code_string, &p_comm_session->p_err_msg);
            if(i_ret == FR_FAIL)
            {
                frfree(p_field_value);
                return APM_L7_ANALYZE_FAIL;
            }

            if(frxml_parser_read(p_field_value,ui_value_len) == FR_SUCC)
            {
                if(i_use_request)
                    snprintf(arr_body_name, sizeof(arr_body_name), "request.http.body.%d", i_content_index);
                else
                    snprintf(arr_body_name, sizeof(arr_body_name), "response.http.body.%d", i_content_index);

                i_ret = frreport_body_l7_add_str(p_st_body_data, arr_body_name, p_field_value);
                if(i_ret == FR_FAIL)
                {
                    frfree(p_field_value);
                    return APM_L7_ANALYZE_FAIL;
                }
            }

            frfree(p_field_value);
        }
        else if(p_form_name)
        {

            // name = '\0'
            //去除换行
            p_field_value = (char *)frmalloc(2 + strlen(p_form_name));
            if(p_field_value == NULL)
            {
                frfree(p_form_name);
                return APM_L7_ANALYZE_FAIL;
            }

            snprintf(p_field_value, 2 + strlen(p_form_name),"%s=", p_form_name);
            frfree(p_form_name);
            p_form_name = NULL;

            if(i_use_request)
                snprintf(arr_body_name, sizeof(arr_body_name), "request.http.body.%d", i_content_index);
            else
                snprintf(arr_body_name, sizeof(arr_body_name), "response.http.body.%d", i_content_index);

            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_body_name, p_field_value);
            frfree(p_field_value);
            if(i_ret == FR_FAIL)
                return APM_L7_ANALYZE_FAIL;

        }

        //文件内容后跟着 \r\n
        p_tcp_body += ui_data_len;
        ui_tcp_body_len -= ui_data_len;

        i_ret = multipart_data_end(&p_tcp_body, &ui_tcp_body_len, p_st_private);
        if(i_ret == APM_L7_ANALYZE_FAIL)
            return APM_L7_ANALYZE_FAIL;

    }

    if(i_use_request)
        i_ret = frreport_body_l7_add_int(p_st_body_data, "request.http.multipart.size", i_content_index);
    else
        i_ret = frreport_body_l7_add_int(p_st_body_data, "response.http.multipart.size", i_content_index);

    return i_ret == FR_SUCC ? APM_L7_ANALYZE_SUCC : APM_L7_ANALYZE_FAIL;
}

/*******************************************************************************
*  FUNC     :  私有信息销毁
*  ARGS     :  p_private_session(http的私有session数据)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
int http_session_reset(void **pp_private_session)
{
    L7session_http_private *p_private_http = (L7session_http_private *)*pp_private_session;

    if(p_private_http != NULL)
    {
        if(p_private_http->p_http1_sess)
            http1_session_destroy(&p_private_http->p_http1_sess);

        if(p_private_http->p_http2_sess)
            http2_session_destroy(&p_private_http->p_http2_sess);

        if(p_private_http->i_version == 1)
            p_private_http->p_http1_sess = http1_session_create();
        else if(p_private_http->i_version == 2)
            p_private_http->p_http2_sess = http2_session_create();
        else
            return FR_FAIL;

        p_private_http->u32_current_resp_id = 0x80000000;
    }

    return FR_SUCC;

}

/*!
 * \brief 头部信息解析
 *
 * \arg p_header            头部key
 *      p_value             头部value
 *      p_st_private        私有数据
 *      p_st_body_data      上报链表
 *      i_flag_needed       是否收集上报数据
 *      i_frame_type        数据类型
 *
 *\return                   FR_SUCC:成功
 *                          FR_FAIL:失败
 *
 */
int http_header_analysis(char *p_header, char *p_value, L7session_http_private *p_st_private, Frreport_body_data *p_st_body_data, int i_flag_needed, int i_frame_type)
{
    char *p_pos = NULL, *p_pos_tmp = NULL;
    unsigned int ui_tmp_len = 0;
    int i_ret = 0;
    Http1_session *p_http1_session = NULL;
    Http2_session *p_http2_session = NULL;
    Http_comm_session *p_comm_session = NULL;

    if(i_flag_needed)
    {
        if(p_header == NULL || p_value == NULL || p_st_private == NULL || p_st_body_data == NULL)
            return FR_FAIL;
    }
    else
    {
        return FR_SUCC;
    }

    if(p_st_private->i_version == 1)
    {
        p_http1_session = p_st_private->p_http1_sess;
        p_comm_session = p_http1_session->p_st_comm_session;
    }
    else if(p_st_private->i_version == 2)
    {
        p_http2_session = p_st_private->p_http2_sess;
        p_comm_session = p_http2_session->p_st_comm_session;
    }

    if(*p_header == ':')
    {
        if(strcmp(p_header, ":method") == 0)
        {
//            if(i_frame_type == 1)
                i_ret = frreport_body_l7_add_str(p_st_body_data, "request.http.method", p_value);
//            else
//                i_ret = frreport_body_l7_add_str(p_st_body_data, "response.promise.http.method", p_value);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

        }
        else if(strcmp(p_header, ":path") == 0)
        {
//            if(i_frame_type == 1)
                p_comm_session->p_uri = frstrdup(p_value);
//            else
//            {
//                i_ret = frreport_body_l7_add_str(p_st_body_data, "response.promise.http.uri", p_value);
//                if(i_ret == FR_FAIL)
//                    return FR_FAIL;
//            }
        }
        else if(strcmp(p_header, ":status") == 0)
        {
            p_comm_session->l_response_code = atoi(p_value);
            p_comm_session->p_code_string = frstrdup(p_value);
        }

        return FR_SUCC;
    }

    if(strcmp(p_header, "content-type") == 0)
    {
        //获取charset
        p_pos = strstr(p_value, "charset=");
        if(p_pos == NULL)
        {
            snprintf(p_comm_session->arr_charset, sizeof(p_comm_session->arr_charset), "%s", "utf-8");
        }
        else
        {
            //指向内容
            p_pos += 8;
            snprintf(p_comm_session->arr_charset, sizeof(p_comm_session->arr_charset), "%s", p_pos);
            p_pos = strchr(p_comm_session->arr_charset, ';');
            if(p_pos)
                *p_pos = '\0';

            frtrim(p_comm_session->arr_charset);
        }

        http_data_type_detect(p_value, p_comm_session);

    }
    else if(strcasecmp(p_header, "content-length") == 0)
    {
        return FR_SUCC;
    }
    else if(strcasecmp(p_header, "host") == 0 && p_comm_session->p_uri)//如果是host，则在末尾添加URL字段
    {
        //host 处理后上报
        p_pos = strchr(p_value, ':');
        if(p_pos)
        {
            //把host后面的 ：置0
            *p_pos = '\0';

            if(frreport_body_l7_add_str (p_st_body_data, "request.http.host", p_value) == FR_FAIL)
            {
                p_pos = NULL;
                return FR_FAIL;
            }
            *p_pos = ':';
        }
        else
        {
            if(frreport_body_l7_add_str (p_st_body_data, "request.http.host", p_value) == FR_FAIL)
                return FR_FAIL;
        }


        //去掉uri中的空格
        frtrim(p_comm_session->p_uri);
        //判断uri是否为完整的host
        if(strncasecmp(p_comm_session->p_uri, "http://", 7) == 0 || strncasecmp(p_comm_session->p_uri, "https://", 8) == 0)
        {
            p_pos_tmp = frstrdup(p_comm_session->p_uri);
            if(p_pos_tmp == NULL)
                return FR_FAIL;

        }
        else
        {
            p_pos = NULL;
            //加"http://"
            if(strcasestr(p_value,"http://") == NULL)
            {
                ui_tmp_len = strlen(p_value) + strlen("http://") + 1;
                p_pos = (char *)frmalloc(ui_tmp_len);
                if(p_pos == NULL)
                    return FR_FAIL;
                snprintf(p_pos, ui_tmp_len, "http://%s", p_value);
                frtrim(p_pos);
            }

            if(p_pos)
            {
                ui_tmp_len = strlen(p_comm_session->p_uri) + strlen(p_pos) + 1;
                p_pos_tmp = (char *)frmalloc(ui_tmp_len);
                if(p_pos_tmp == NULL)
                {
                    frfree(p_pos);
                    return FR_FAIL;
                }

                snprintf(p_pos_tmp, ui_tmp_len, "%s%s", p_pos, p_comm_session->p_uri);
                frfree(p_pos);
            }
            else
            {
                //增加URI
                ui_tmp_len = strlen(p_comm_session->p_uri) + strlen(p_value) + 1;
                p_pos_tmp = (char *)frmalloc(ui_tmp_len);
                if(p_pos_tmp == NULL)
                    return FR_FAIL;

                snprintf(p_pos_tmp, ui_tmp_len, "%s%s", p_value, p_comm_session->p_uri);
            }

        }

        //title
        i_ret = frreport_body_l7_add_str(p_st_body_data, "request.http.url", p_pos_tmp);
        if(i_ret == FR_FAIL)
        {
            frfree(p_pos_tmp);
            return FR_FAIL;
        }

        //transaction.title
        p_pos = strchr(p_pos_tmp, '?');
        if(p_pos)
            *p_pos = '\0';

        if(p_http2_session->p_title)
            frfree(p_http2_session->p_title);

        p_http2_session->p_title = p_pos_tmp;
        p_pos_tmp = NULL;
//        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_TRANS_TITLE, p_pos_tmp);
//        if(i_ret == FR_FAIL)
//        {
//            frfree(p_pos_tmp);
//            return FR_FAIL;
//        }
//
//        frfree(p_pos_tmp);
        return FR_SUCC;

    }
    else if(strcasecmp(p_header, "Authorization") == 0)
    {
        //
        i_ret = http_auth_parse(p_st_body_data, p_value, p_st_private);
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        return FR_SUCC;
    }
    //存到结构体中
    frtrim(p_value);

    //字段名过滤
    i_ret = http_field_name_filter(p_header);
    if(i_ret == FR_FAIL)
        return FR_SUCC;

    //p_header修改
    if(i_frame_type == 1)
        ui_tmp_len = strlen(p_header) + strlen("request.http.header.") + 1;
    else if(i_frame_type == 2)
        ui_tmp_len = strlen(p_header) + strlen("response.http.header.") + 1;
    else
        ui_tmp_len = strlen(p_header) + strlen("request.http.header.") + 1;

    p_pos = (char *)frmalloc(ui_tmp_len);
    if(p_pos == NULL)
        return FR_FAIL;

    if(i_frame_type == 1)
        snprintf(p_pos, ui_tmp_len, "request.http.header.%s", p_header);
    else if(i_frame_type == 2)
        snprintf(p_pos, ui_tmp_len, "response.http.header.%s", p_header);
    else
        snprintf(p_pos, ui_tmp_len, "request.http.header.%s", p_header);

    i_ret = frreport_body_l7_add_str(p_st_body_data, p_pos, p_value);
    if(i_ret == FR_FAIL)
    {
        frfree(p_pos);
        return FR_FAIL;
    }

    frfree(p_pos);
    return FR_SUCC;

}

/*!
 * \brief gzip数据二次判断并解析
 *
 * \arg p_comm_session              http相关信息
 *      p_st_body_data              上报链表
 *      p_tcp_body                  数据内容
 *      ui_tcp_body_len             数据长度
 *      i_use_request               是否为request
 *
 * \return                          APM_L7_ANALYZE_FAIL  (解析失败)
*                                   APM_L7_ANALYZE_TODO  (解析未完)
*                                   APM_L7_ANALYZE_SUCC  (解析结束）
 *
 */
int gzip_data_redetect(Http_comm_session *p_comm_session, Frreport_body_data *p_st_body_data, char *p_tcp_body, unsigned int ui_tcp_body_len, int i_use_request)
{
    Frbyte_Packet *p_packet = NULL;
    int i_ret = 0;
    unsigned int ui_header_buff_len = 0;
    unsigned long ul_zdata_len = 0;
    char *p_header_buff = NULL, *p_zdata = NULL;
    char *p_chunked = NULL;
    unsigned int ui_chunked_len = 0;
    char arr_head[256];

    if(p_comm_session == NULL || p_st_body_data == NULL)
        return APM_L7_ANALYZE_FAIL;

    p_packet = p_comm_session->p_st_data;
    if(p_packet == NULL)
    {
        p_comm_session->p_st_data = bytebuff_creat();
        p_packet = p_comm_session->p_st_data;
        if(p_packet == NULL)
            return APM_L7_ANALYZE_FAIL;
    }

    //取得完整的响应数据块
    i_ret = bytebuff_add(p_packet, p_tcp_body, ui_tcp_body_len);
    if(i_ret != FR_SUCC)
        return APM_L7_ANALYZE_FAIL;

    //判断是否结束
    if(p_comm_session->i_flag_chunk)
    {
        i_ret = http_chunk_data_get(p_packet, p_comm_session);
        if(i_ret == -1)
            return APM_L7_ANALYZE_FAIL;
        else if(i_ret == 1)
            return APM_L7_ANALYZE_TODO;
        else
            bytebuff_rewind(p_packet);
    }
    else
    {
        ui_header_buff_len = (unsigned int)bytebuff_length(p_packet);
        if(p_comm_session->i_data_len > (int)ui_header_buff_len)
            return APM_L7_ANALYZE_TODO;
    }

    ui_header_buff_len = (unsigned int)bytebuff_length(p_packet);
    p_header_buff = (char *)frmalloc(ui_header_buff_len + 1);
    i_ret = bytebuff_get_bytes(p_packet, p_header_buff, ui_header_buff_len);
    if(i_ret == FR_FAIL)
    {
        frfree(p_header_buff);
        return APM_L7_ANALYZE_FAIL;
    }
    p_header_buff[ui_header_buff_len] = '\0';
    bytebuff_free(&p_comm_session->p_st_data);
    
    if(p_comm_session->i_flag_chunk)
    {
        i_ret = de_chunked((unsigned char *)p_header_buff, ui_header_buff_len, &p_chunked, (unsigned long *)&ui_chunked_len);
        frfree(p_header_buff);
        if(i_ret == -1)
            return APM_L7_ANALYZE_FAIL;
        
        p_header_buff = p_chunked;
        ui_header_buff_len = ui_chunked_len;
    }
    
    //gzip 数据解压
    i_ret = frgzip_decompress((Byte *)p_header_buff, ui_header_buff_len, &p_zdata, &ul_zdata_len);
    frfree(p_header_buff);
    if(i_ret != FR_SUCC)
    {
        if(p_zdata)
            frfree(p_zdata);

        return APM_L7_ANALYZE_FAIL;
    }
    
    p_header_buff = p_zdata;
    ui_header_buff_len = (unsigned int) ul_zdata_len;
    
    p_comm_session->i_flag_need = 0;
    i_ret = http_bodydata_type_detect(p_comm_session, p_header_buff, ui_header_buff_len);
    if(i_ret == FR_FAIL)
    {
        frfree(p_header_buff);
        return APM_L7_ANALYZE_FAIL;
    }

    if(p_comm_session->i_flag_need == 2)
    {
        frfree(p_header_buff);
        return APM_L7_ANALYZE_SUCC;
    }
    
    //如果不是chunk格式则存在p_st_private->i_data_len
    if(p_comm_session->i_flag_data_type == HTTP_XML_DATA)
    {
        if(i_use_request)
        {
            i_ret = frsoap_parse_req(p_header_buff, ui_header_buff_len, p_st_body_data);
            if(i_ret == FR_FAIL)
            {
                frfree(p_header_buff);
                return APM_L7_ANALYZE_FAIL;
            }
        }
        else
        {
            i_ret = frsoap_parse_resp(p_header_buff, ui_header_buff_len, p_st_body_data, &p_comm_session->p_code_string, &p_comm_session->p_err_msg);
            if(i_ret == FR_FAIL)
            {
                frfree(p_header_buff);
                return APM_L7_ANALYZE_FAIL;
            }
        }

        //字段名
        if(i_use_request)
            snprintf(arr_head, sizeof(arr_head), "request.http.body.%d", 1);
        else
            snprintf(arr_head, sizeof(arr_head), "response.http.body.%d", 1);

        i_ret = frreport_body_l7_add_str(p_st_body_data, arr_head, p_header_buff);
        if(i_ret == FR_FAIL)
        {
            frfree(p_header_buff);
            return APM_L7_ANALYZE_FAIL;
        }
        p_comm_session->p_xml_data = frstrdup(p_header_buff);
        if(p_comm_session->p_xml_data == NULL)
        {
            frfree(p_header_buff);
            return APM_L7_ANALYZE_FAIL;
        }

            #ifdef FRDBG_XML_DATA_OUTPUT
            FILE *fp_xml_data = NULL;
            struct timeval st_time;
            char arr_tmp[128];

            gettimeofday (&st_time, NULL);
            snprintf(arr_tmp, sizeof(arr_tmp), "%d%d.txt", st_time.tv_sec, st_time.tv_usec);
            fp_xml_data = fopen(arr_tmp,"w");
            if(fp_xml_data)
            {
                fprintf(fp_xml_data, "%s\n", p_header_buff);
                fclose(fp_xml_data);
            }
            #endif
        frfree(p_header_buff);
    }
    else if(p_comm_session->i_flag_data_type == HTTP_JSON_DATA)
    {
        //字段名
        if(i_use_request)
            snprintf(arr_head, sizeof(arr_head), "request.http.body.%d", 1);
        else
            snprintf(arr_head, sizeof(arr_head), "response.http.body.%d", 1);

        i_ret = frreport_body_l7_add_str(p_st_body_data, arr_head, p_header_buff);
        if(i_ret == FR_FAIL)
        {
            frfree(p_header_buff);
            return APM_L7_ANALYZE_FAIL;
        }
        frfree(p_header_buff);
    }
    else
    {
        //字段名
        if(i_use_request)
            snprintf(arr_head, sizeof(arr_head), "request.http.body_tmp.%d", 1);
        else
            snprintf(arr_head, sizeof(arr_head), "response.http.body_tmp.%d", 1);

        i_ret = frreport_body_l7_add_str(p_st_body_data, arr_head, p_header_buff);
        if(i_ret == FR_FAIL)
        {
            frfree(p_header_buff);
            return APM_L7_ANALYZE_FAIL;
        }
        frfree(p_header_buff);
    }

    p_comm_session->i_flag_data_type = HTTP_UNSET_DATA;
    return APM_L7_ANALYZE_SUCC;

}

/*******************************************************************************
*  FUNC     :  获取完整的响应数据
*  ARGS     ： p_st_private         (私有数据)
*           :  p_tcp_body           (指向信息头)
*           :  ui_tcp_body_len       (信息长度)
*  RTN      :  APM_L7_ANALYZE_FAIL  (解析失败)
*           :  APM_L7_ANALYZE_TODO  (解析未完)
*           :  APM_L7_ANALYZE_SUCC  (解析结束）
*  NOTE     :
*******************************************************************************/
int get_req_data(L7session_http_private *p_st_private, Frreport_body_data *p_st_body_data, char *p_tcp_body, unsigned int ui_tcp_body_len)
{
    Frbyte_Packet *p_packet = NULL;
    int i_ret = 0;
    char *p_header_buff = NULL, *p_tmp = NULL;
    unsigned int ui_header_buff_len = 0;
    char arr_head[128];
    Http1_session *p_http1_session = NULL;
    Http2_session *p_http2_session = NULL;
    Http_comm_session *p_comm_session = NULL;

    if(p_st_private == NULL || p_tcp_body == NULL || p_st_body_data == NULL)
        return APM_L7_ANALYZE_FAIL;

    if(p_st_private->i_version == 1)
    {
        p_http1_session = p_st_private->p_http1_sess;
        p_comm_session = p_http1_session->p_st_comm_session;
    }
    else if(p_st_private->i_version == 2)
    {
        p_http2_session = p_st_private->p_http2_sess;
        p_comm_session = p_http2_session->p_st_comm_session;
    }

    if(ui_tcp_body_len == 0)
        return p_comm_session->i_data_len > 0 ? APM_L7_ANALYZE_TODO:APM_L7_ANALYZE_SUCC;

    
    if(p_comm_session->i_flag_need == 0
        || p_comm_session->i_flag_data_type == HTTP_TEXT_DATA)
    {
        i_ret = http_bodydata_type_detect(p_comm_session, p_tcp_body, ui_tcp_body_len);
        if(i_ret == FR_FAIL)
            return APM_L7_ANALYZE_FAIL;
    }
    
    if(p_comm_session->i_flag_need == 0)
        http_suffixdetect(p_comm_session->p_uri, p_comm_session);
    
    if(p_comm_session->i_flag_data_type == HTTP_GZIP_DATA)
    {
        i_ret = gzip_data_redetect(p_comm_session, p_st_body_data, p_tcp_body, ui_tcp_body_len, FR_YES);
        return i_ret;
    }

    //获取数据
    if(p_comm_session->i_flag_need == 2)
    {
        //如果没有长度标识 req 不会有chunk
        if(p_comm_session->i_data_len == 0)
        {
            if(p_comm_session->p_st_data == NULL)
            {
                p_comm_session->p_st_data = bytebuff_creat();
                if(p_comm_session->p_st_data == NULL)
                    return APM_L7_ANALYZE_FAIL;
            }

            return APM_L7_ANALYZE_TODO;
        }

        p_comm_session->i_data_len -= ui_tcp_body_len;
        if(p_comm_session->i_data_len > 0)
            return APM_L7_ANALYZE_TODO;
        else
            return APM_L7_ANALYZE_SUCC;
    }

    p_packet = p_comm_session->p_st_data;
    if(p_packet == NULL)
    {
        p_comm_session->p_st_data = bytebuff_creat();
        p_packet = p_comm_session->p_st_data;
        if(p_packet == NULL)
            return APM_L7_ANALYZE_FAIL;
    }

    //取得完整的响应数据块
    i_ret = bytebuff_add(p_packet, p_tcp_body, ui_tcp_body_len);
    if(i_ret != FR_SUCC)
        return APM_L7_ANALYZE_FAIL;

    //获取整个数据块
    ui_header_buff_len = (unsigned int)bytebuff_length(p_packet);
    if(p_comm_session->i_data_len > (int)ui_header_buff_len)
        return APM_L7_ANALYZE_TODO;
    
    //扩展协议解析
    i_ret = frhttp_extend_bodydata_deal(p_packet, p_comm_session, p_st_body_data, FR_YES);
    if(i_ret == HTTP_EXTEND_DONE_SUCC)
        return APM_L7_ANALYZE_SUCC;
    else if(i_ret == HTTP_EXTEND_DONE_FAIL)
        goto ERROR;
    
    //如果不是扩展协议  取出内容块解析
    p_header_buff = (char *)frmalloc(ui_header_buff_len + 1);
    if(p_header_buff == NULL)
        goto ERROR;
    i_ret = bytebuff_peek_bytes(p_packet, p_header_buff, ui_header_buff_len);
    if(i_ret == FR_FAIL)
        goto ERROR;
    p_header_buff[ui_header_buff_len] = '\0';

    if(p_comm_session->i_flag_multipart)
    {
        i_ret = multipart_data_parse(p_header_buff, ui_header_buff_len, p_st_body_data, p_st_private, FR_YES);
        frfree(p_header_buff);
        return i_ret;
    }

//    //没有content-type 字段
//    if(p_comm_session->i_flag_need == 0)
//    {
//        if(frxml_detect(p_header_buff,ui_header_buff_len) == FR_FAIL)
//        {
//            //如果没有XML头 则尝试解析
//            ui_tmp_len = ui_header_buff_len + strlen("<?xml version='1.0' encoding='UTF-8'?>\n");
//            p_tmp = (char *)frmalloc(ui_tmp_len + 1);
//            if(p_tmp == NULL)
//                return APM_L7_ANALYZE_FAIL;
//
//            snprintf(p_tmp, ui_tmp_len + 1, "<?xml version='1.0' encoding='UTF-8'?>\n%s", p_header_buff);
//
//            if(frxml_parser_read(p_tmp, ui_tmp_len) == FR_SUCC)
//            {
//                frfree(p_header_buff);
//                ui_header_buff_len = ui_tmp_len;
//                p_header_buff = p_tmp;
//                p_tmp = NULL;
//                p_comm_session->i_flag_need = 1;
//                p_comm_session->i_flag_data_type = HTTP_XML_DATA;
//            }
//            else
//            {
//                p_comm_session->i_flag_need = 2;
//                frfree(p_tmp);
//                p_tmp = NULL;
//            }
//        }
//        else
//        {
//            p_comm_session->i_flag_need = 1;
//            p_comm_session->i_flag_data_type = HTTP_XML_DATA;
//        }
//    }

    //soap 尝试解析
    if(p_comm_session->i_flag_data_type == HTTP_XML_DATA)
    {
        i_ret = frsoap_parse_req(p_header_buff, ui_header_buff_len, p_st_body_data);
        if(i_ret == FR_FAIL)
            goto ERROR;
    }

    //url decode
    if(p_comm_session->i_url_encoded)
    {
        //url decode
        if(http_url_decode(p_header_buff, ui_header_buff_len, &p_tmp) == FR_FAIL)
            goto ERROR;

        frfree(p_header_buff);
        p_header_buff = p_tmp;
        p_tmp = NULL;
    }
    
    if(p_comm_session->i_flag_need == 1 && p_comm_session->arr_charset[0]!= '\0'
       && (strcasecmp(p_comm_session->arr_charset, "utf-8") != 0 && strcasecmp(p_comm_session->arr_charset, "utf8") != 0))
    {
        i_ret = iconv_to_utf8(p_header_buff, strlen(p_header_buff), p_comm_session->arr_charset, &p_tmp, &ui_header_buff_len);
        if(i_ret != 0)
            goto ERROR;

        frfree(p_header_buff);
        p_header_buff = p_tmp;
        p_tmp = NULL;
    }

    //http.body
    if(p_comm_session->i_flag_data_type == HTTP_OTHERS_DATA)
        snprintf(arr_head, sizeof(arr_head), "request.http.body_tmp.%d", 1);
    else
        snprintf(arr_head, sizeof(arr_head), "request.http.body.%d", 1);
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_head, p_header_buff);
    frfree(p_header_buff);

    bytebuff_free(&p_comm_session->p_st_data);
    return i_ret == FR_SUCC ? APM_L7_ANALYZE_SUCC : APM_L7_ANALYZE_FAIL;

ERROR:
    if(p_header_buff)
        frfree(p_header_buff);

    if(p_tmp)
        frfree(p_tmp);

    return APM_L7_ANALYZE_FAIL;
}



/*******************************************************************************
*  FUNC     :  获取完整的响应数据
*  ARGS     ： p_st_private         (私有数据)
*           :  p_tcp_body           (指向信息头)
*           :  ui_tcp_body_len       (信息长度)
*  RTN      :  APM_L7_ANALYZE_FAIL  (解析失败)
*           :  APM_L7_ANALYZE_TODO  (解析未完)
*           :  APM_L7_ANALYZE_SUCC  (解析结束）
*  NOTE     :
*******************************************************************************/
int get_resp_data(L7session_http_private *p_st_private, Frreport_body_data *p_st_body_data, char *p_tcp_body, unsigned int ui_tcp_body_len)
{
    char *p_zdata = NULL;
    char *p_chunk_data = NULL;
    unsigned long ul_zdata_len = 0;
    Frbyte_Packet *p_packet = NULL, *p_st_rmi = NULL;
    int i_ret = 0;
    char *p_body_buff = NULL;
    unsigned int ui_body_buff_len = 0;
    char *p_body_buff_tmp = NULL;
    char arr_head[128];
    Http1_session *p_http1_session = NULL;
    Http2_session *p_http2_session = NULL;
    Http_comm_session *p_comm_session = NULL;
    char *p_pos = NULL;

    if(p_st_private == NULL || p_tcp_body == NULL || p_st_body_data == NULL)
        return APM_L7_ANALYZE_FAIL;

    if(p_st_private->i_version == 1)
    {
        p_http1_session = p_st_private->p_http1_sess;
        p_comm_session = p_http1_session->p_st_comm_session;
    }
    else if(p_st_private->i_version == 2)
    {
        p_http2_session = p_st_private->p_http2_sess;
        p_comm_session = p_http2_session->p_st_comm_session;
    }

    if(ui_tcp_body_len == 0)
    {
        if(p_comm_session->i_flag_chunk)
            return APM_L7_ANALYZE_TODO;
        else if (p_comm_session->i_data_len > 0)
            return APM_L7_ANALYZE_TODO;
        else
            return APM_L7_ANALYZE_SUCC;
    }
    
    //判断是否保存数据 并上报
    if(p_comm_session->i_flag_need == 0
       || p_comm_session->i_flag_data_type == HTTP_TEXT_DATA)
    {
        if(p_comm_session->i_flag_chunk)
        {
            p_pos = strstr(p_tcp_body, "\r\n");
        
            //如果chunk长度位超过8 返回失败
            if(p_pos == NULL || p_pos - p_tcp_body > 10)
                return APM_L7_ANALYZE_FAIL;
        
        
            i_ret = http_bodydata_type_detect(p_comm_session, p_pos + 2, ui_tcp_body_len - (p_pos - p_tcp_body + 2));
            if(i_ret == FR_FAIL)
                return APM_L7_ANALYZE_FAIL;
        
        }
        else
        {
            i_ret = http_bodydata_type_detect(p_comm_session, p_tcp_body, ui_tcp_body_len);
            if(i_ret == FR_FAIL)
                return APM_L7_ANALYZE_FAIL;
        }
    }
    
    if(p_comm_session->i_flag_data_type == HTTP_GZIP_DATA)
    {
        i_ret = gzip_data_redetect(p_comm_session, p_st_body_data, p_tcp_body, ui_tcp_body_len, FR_NO);
        return i_ret;
    }
    
    if(p_comm_session->i_flag_need == 0)
        http_suffixdetect(p_comm_session->p_uri, p_comm_session);

    //获取所需要的数据
    if(p_comm_session->i_flag_need == 1)
    {
        
        //获取完整数据
        p_packet = p_comm_session->p_st_data;
        if(p_packet == NULL)
        {
            p_comm_session->p_st_data = bytebuff_creat();
            p_packet = p_comm_session->p_st_data;
            if(p_packet == NULL)
                return APM_L7_ANALYZE_FAIL;
        }

        //取得完整的响应数据块
        i_ret = bytebuff_add(p_packet, p_tcp_body, ui_tcp_body_len);
        if(i_ret != FR_SUCC)
            return APM_L7_ANALYZE_FAIL;

        //判断是否结束
        if(p_comm_session->i_flag_chunk)
        {
            i_ret = http_chunk_data_get(p_packet, p_comm_session);
            if(i_ret == -1)
                return APM_L7_ANALYZE_FAIL;
            else if(i_ret == 1)
                return APM_L7_ANALYZE_TODO;
            else
                bytebuff_rewind(p_packet);
        }
        else
        {
            ui_body_buff_len = (unsigned int)bytebuff_length(p_packet);
            if(p_comm_session->i_data_len > (int)ui_body_buff_len)
                return APM_L7_ANALYZE_TODO;
        }
        
        //chunk 反解析
        if(p_comm_session->i_flag_chunk)
        {
            //取出内存块 chunk解码
            ui_body_buff_len = (unsigned int)bytebuff_length(p_packet);
            //获取整个数据块
            p_body_buff = (char *)frmalloc(ui_body_buff_len + 1);
            if(p_body_buff == NULL)
                return APM_L7_ANALYZE_FAIL;
            i_ret = bytebuff_peek_bytes(p_packet, p_body_buff, ui_body_buff_len);
            if(i_ret == FR_FAIL)
            {
                frfree(p_body_buff);
                return APM_L7_ANALYZE_FAIL;
            }
            p_body_buff[ui_body_buff_len] = '\0';
    
            //body数据存入内存块 释放bytebuffer
            bytebuff_free(&p_comm_session->p_st_data);
            //chunk解析
            i_ret = de_chunked((unsigned char *)p_body_buff, ui_body_buff_len, &p_chunk_data, &ul_zdata_len);
            frfree(p_body_buff);
            if(i_ret != 1)
                return APM_L7_ANALYZE_FAIL;
    
            //判断chunk的时候 是否有协议扩展
            if(frhttp_body_extended(p_comm_session))
            {
                p_st_rmi = bytebuff_creat();
                if(p_st_rmi == NULL)
                    return APM_L7_ANALYZE_FAIL;
        
                i_ret = bytebuff_add(p_st_rmi, p_chunk_data, ul_zdata_len);
                frfree(p_chunk_data);
                if(i_ret == FR_FAIL)
                    return APM_L7_ANALYZE_FAIL;
                
                //如果是rmi yongyou的数据 直接传bytebuffer 解析
                i_ret = frhttp_extend_bodydata_deal(p_st_rmi, p_comm_session, p_st_body_data, FR_NO);
                bytebuff_free(&p_st_rmi);
                if(i_ret == HTTP_EXTEND_DONE_SUCC)
                    return APM_L7_ANALYZE_SUCC;
                else if(i_ret == HTTP_EXTEND_DONE_FAIL)
                    return APM_L7_ANALYZE_FAIL;
                
                return APM_L7_ANALYZE_SUCC;
                
            }
    
            //如果不是扩展协议  取出内容块解析
            p_body_buff = p_chunk_data;
            p_chunk_data = NULL;
            ui_body_buff_len = ul_zdata_len;
        }
        else
        {
            //如果是rmi yongyou的数据 直接传bytebuffer 解析
            i_ret = frhttp_extend_bodydata_deal(p_packet, p_comm_session, p_st_body_data, FR_NO);
            if(i_ret == HTTP_EXTEND_DONE_SUCC)
                return APM_L7_ANALYZE_SUCC;
            else if(i_ret == HTTP_EXTEND_DONE_FAIL)
                return APM_L7_ANALYZE_FAIL;
    
            //如果不是扩展协议  取出内容块解析
            ui_body_buff_len = (unsigned int)bytebuff_length(p_packet);
            //获取整个数据块
            p_body_buff = (char *)frmalloc(ui_body_buff_len + 1);
            if(p_body_buff == NULL)
                return APM_L7_ANALYZE_FAIL;
            i_ret = bytebuff_peek_bytes(p_packet, p_body_buff, ui_body_buff_len);
            if(i_ret == FR_FAIL)
            {
                frfree(p_body_buff);
                return APM_L7_ANALYZE_FAIL;
            }
            p_body_buff[ui_body_buff_len] = '\0';

            //body数据存入内存块 释放bytebuffer
            bytebuff_free(&p_comm_session->p_st_data);
            
        }
    
        //multipart
        if(p_comm_session->i_flag_multipart)
        {
            i_ret = multipart_data_parse(p_body_buff, ui_body_buff_len, p_st_body_data, p_st_private, FR_NO);
            frfree(p_body_buff);
            return i_ret;
        }
    
        //gizp解压
        if(p_comm_session->i_flag_gzip)
        {
            i_ret = frgzip_decompress((Byte *)p_body_buff, ui_body_buff_len, &p_zdata, &ul_zdata_len);
            frfree(p_body_buff);
            if(i_ret != FR_SUCC)
            {
                if(p_zdata)
                    frfree(p_zdata);
            
                return APM_L7_ANALYZE_FAIL;
            }
    
            p_body_buff = p_zdata;
            ui_body_buff_len = (unsigned int)ul_zdata_len;
        
        }
        else if(p_comm_session->i_flag_deflate)
        {
            //不用解压
            p_body_buff_tmp = (char *)frmalloc(ui_body_buff_len + 10);
            memcpy(p_body_buff_tmp,"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00",10);
            memcpy(p_body_buff_tmp + 10,p_body_buff,ui_body_buff_len);
            ui_body_buff_len += 10;
            frfree(p_body_buff);
            p_body_buff = p_body_buff_tmp;
        
            i_ret = frgzip_decompress((Byte *)p_body_buff, ui_body_buff_len, &p_zdata, &ul_zdata_len);
            frfree(p_body_buff);
            if(i_ret != FR_SUCC)
            {
                if(p_zdata)
                    frfree(p_zdata);
            
                return APM_L7_ANALYZE_FAIL;
            }
    
            p_body_buff = p_zdata;
            ui_body_buff_len = (unsigned int)ul_zdata_len;
        
        }
        
        if(p_comm_session->i_flag_need ==1 && p_comm_session->arr_charset[0]!= '\0'
           && (strcasecmp(p_comm_session->arr_charset, "utf-8") != 0) && strcasecmp(p_comm_session->arr_charset, "utf8") != 0)
        {
            i_ret = iconv_to_utf8(p_body_buff, ui_body_buff_len, p_comm_session->arr_charset, &p_zdata, (unsigned int *)&ul_zdata_len);
            if(i_ret != 0)
            {
                if(p_zdata)
                    frfree(p_zdata);

                if(p_body_buff)
                    frfree(p_body_buff);

                return APM_L7_ANALYZE_FAIL;
            }

            frfree(p_body_buff);
            p_body_buff = p_zdata;
            ui_body_buff_len = (unsigned int )ul_zdata_len;
        }

        //如果不是chunk格式则存在p_st_private->i_data_len
        if(p_comm_session->i_flag_data_type == HTTP_XML_DATA)
        {
            i_ret = frsoap_parse_resp(p_body_buff, ui_body_buff_len, p_comm_session->p_st_body_data_resp, &p_comm_session->p_code_string, &p_comm_session->p_err_msg);
            if(i_ret == FR_FAIL)
            {
                frfree(p_zdata);
                return APM_L7_ANALYZE_FAIL;
            }

            //字段名
            snprintf(arr_head, sizeof(arr_head), "response.http.body.%d", 1);
            i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, arr_head, p_body_buff);
            if(i_ret == FR_FAIL)
            {
                frfree(p_body_buff);
                return APM_L7_ANALYZE_FAIL;
            }
            
            p_comm_session->p_xml_data = frstrdup(p_body_buff);
            if(p_comm_session->p_xml_data == NULL)
            {
                frfree(p_body_buff);
                return APM_L7_ANALYZE_FAIL;
            }

#ifdef FRDBG_XML_DATA_OUTPUT
            FILE *fp_xml_data = NULL;
            struct timeval st_time;
            char arr_tmp[128];

            gettimeofday (&st_time, NULL);
            snprintf(arr_tmp, sizeof(arr_tmp), "%d%d.txt", st_time.tv_sec, st_time.tv_usec);
            fp_xml_data = fopen(arr_tmp,"w");
            if(fp_xml_data)
            {
                fprintf(fp_xml_data, "%s\n", p_body_buff);
                fclose(fp_xml_data);
            }
#endif
            frfree(p_body_buff);
        }
        else if(p_comm_session->i_flag_data_type == HTTP_JSON_DATA)
        {
            //字段名
            snprintf(arr_head, sizeof(arr_head), "response.http.body.%d", 1);
            i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, arr_head, p_body_buff);
            if(i_ret == FR_FAIL)
            {
                frfree(p_body_buff);
                return APM_L7_ANALYZE_FAIL;
            }
            frfree(p_body_buff);
        }
        else if(p_comm_session->i_flag_data_type == HTTP_OTHERS_DATA)
        {
            //字段名
            snprintf(arr_head, sizeof(arr_head), "response.http.body_tmp.%d", 1);
            i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, arr_head, p_body_buff);
            if(i_ret == FR_FAIL)
            {
                frfree(p_body_buff);
                return APM_L7_ANALYZE_FAIL;
            }
            frfree(p_body_buff);
        }
        else
        {
            frfree(p_body_buff);
        }

        return APM_L7_ANALYZE_SUCC;
    }
    else
    {
        if(p_comm_session->i_flag_chunk)
        {
        	i_ret = http_chunk_data_skip(p_tcp_body, ui_tcp_body_len, p_comm_session);
        	if (i_ret == -1)
        		return APM_L7_ANALYZE_FAIL;
            else if (i_ret == HTTP_CHUNK_TODO)
            	return APM_L7_ANALYZE_TODO;
            else
            	return APM_L7_ANALYZE_SUCC;
        }
        else if((unsigned int)p_comm_session->i_data_len > ui_tcp_body_len)
        {
            p_comm_session->i_data_len -= ui_tcp_body_len;
            return APM_L7_ANALYZE_TODO;
        }
        else
        {
            return APM_L7_ANALYZE_SUCC;
        }
    }

    return APM_L7_ANALYZE_SUCC;

}


/*!
 * \brief HTTP/1.0短连接是 request数据上报
 *
 */

int http_req_report(L7session_http_private *p_st_private, Frhash_header *p_st_hash_report)
{
    int i_ret = 0;
    Http1_session *p_http1_session = NULL;
    Http_comm_session *p_comm_session = NULL;
    L4_transaction *p_st_l4_trans = NULL;
    Frreport_data *p_st_report_data = NULL;
    Frbyte_Packet *p_packet = NULL;
    unsigned long ul_tmp = 0;
    char *p_header_buff = NULL, *p_tmp = NULL;
    unsigned int ui_header_buff_len = 0;
    char arr_head[256];

    if(p_st_private == NULL || p_st_private->p_http1_sess == NULL)
        return APM_L7_ANALYZE_FAIL;

    p_http1_session = p_st_private->p_http1_sess;
    p_comm_session = p_http1_session->p_st_comm_session;
    if(p_comm_session == NULL)
        return APM_L7_ANALYZE_FAIL;

    p_st_l4_trans = &p_comm_session->st_l4_trans;

    if(p_comm_session->p_st_body_data_req == NULL)
        return APM_L7_ANALYZE_FAIL;

    //数据处理
    if(p_comm_session->i_flag_need == 1)
    {
        //扩展协议解析
        i_ret = frhttp_extend_bodydata_deal(p_packet, p_comm_session, p_comm_session->p_st_body_data_req, FR_YES);
        if(i_ret == HTTP_EXTEND_DONE_SUCC)
            return APM_L7_ANALYZE_SUCC;
        else if(i_ret == HTTP_EXTEND_DONE_FAIL)
            goto ERROR;

        //如果不是扩展协议  取出内容块解析
        p_header_buff = (char *)frmalloc(ui_header_buff_len + 1);
        if(p_header_buff == NULL)
            goto ERROR;
        i_ret = bytebuff_peek_bytes(p_packet, p_header_buff, ui_header_buff_len);
        if(i_ret == FR_FAIL)
            goto ERROR;
        p_header_buff[ui_header_buff_len] = '\0';

        if(p_comm_session->i_flag_multipart)
        {
            i_ret = multipart_data_parse(p_header_buff, ui_header_buff_len, p_comm_session->p_st_body_data_req, p_st_private, FR_YES);
            frfree(p_header_buff);
            return i_ret;
        }

        //soap 尝试解析
        if(p_comm_session->i_flag_data_type == HTTP_XML_DATA)
        {
            i_ret = frsoap_parse_req(p_header_buff, ui_header_buff_len, p_comm_session->p_st_body_data_req);
            if(i_ret == FR_FAIL)
                goto ERROR;
        }

        //url decode
        if(p_comm_session->i_url_encoded)
        {
            //url decode
            if(http_url_decode(p_header_buff, ui_header_buff_len, &p_tmp) == FR_FAIL)
                goto ERROR;

            frfree(p_header_buff);
            p_header_buff = p_tmp;
            p_tmp = NULL;
        }
    
        if(p_comm_session->i_flag_need == 1 && p_comm_session->arr_charset[0]!= '\0'
           && (strcasecmp(p_comm_session->arr_charset, "utf-8") != 0 && strcasecmp(p_comm_session->arr_charset, "utf8") != 0))
        {
            i_ret = iconv_to_utf8(p_header_buff, strlen(p_header_buff), p_comm_session->arr_charset, &p_tmp, &ui_header_buff_len);
            if(i_ret != 0)
                goto ERROR;

            frfree(p_header_buff);
            p_header_buff = p_tmp;
            p_tmp = NULL;
        }

        //http.body
        snprintf(arr_head, sizeof(arr_head), "request.http.body.%d", 1);
        i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_req, arr_head, p_header_buff);
        if(i_ret == FR_FAIL)
        {
            frfree(p_header_buff);
            return APM_L7_ANALYZE_FAIL;
        }

        frfree(p_header_buff);
        bytebuff_free(&p_comm_session->p_st_data);
    }
    else
    {
        bytebuff_free(&p_comm_session->p_st_data);
    }


    p_http1_session->i_flag_req_finish = 0;

    //request_time_us
    ul_tmp = (unsigned long)frtime_diff(&(p_st_l4_trans->st_request_time_first_byte), &p_st_l4_trans->st_request_time);
    if(frreport_body_l7_add_ulong(p_comm_session->p_st_body_data_req, APM_REPORT_KEY_REQ_SEND_TIME_US, ul_tmp) == FR_FAIL)
        goto ERROR;

    //响应字节数
    if(frreport_body_l7_add_long(p_comm_session->p_st_body_data_req, APM_REPORT_KEY_REQ_DATA_BYTES, p_st_l4_trans->l_request_bytes) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_timeval(p_comm_session->p_st_body_data_req, APM_REPORT_KEY_REQ_END_TIMESTAMP, &p_st_l4_trans->st_request_time) == FR_FAIL)
        goto ERROR;

    //session 数据处理
    if(p_st_private->p_user_name)
    {
        i_ret = http_session_report(p_comm_session->p_st_body_data_req, p_st_private);
        if(i_ret == FR_FAIL)
            goto ERROR;
    }

    //数据上报
    p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_REQ);
    if(p_st_report_data == NULL)
        goto ERROR;

    //保存req数据
    p_comm_session->p_lst_req_tmp = FRREPORT_BODY_L7LIST_CLONE_REQ(p_comm_session->p_st_body_data_req);
    if(p_comm_session->p_lst_req_tmp == NULL)
        goto ERROR;

    //保存conn数据
    p_comm_session->p_lst_comm_tmp = FRREPORT_BODY_L7LIST_CLONE_COMM(p_comm_session->p_st_body_data_req);
    if(p_comm_session->p_lst_comm_tmp == NULL)
        goto ERROR;

    if(frreport_data_add_body(p_st_report_data, p_comm_session->p_st_body_data_req) == FR_FAIL)
        goto ERROR;
    p_comm_session->p_st_body_data_req = NULL;

    if(frreport_data_hash(p_st_hash_report, p_st_report_data) == FR_FAIL)
        goto ERROR;
    p_st_report_data = NULL;

    //req数据上报结束
    p_comm_session->i_flag_multipart = 0;
    p_comm_session->i_flag_chunk = 0;
    p_comm_session->i_flag_need = 0;
    p_comm_session->i_data_len = 0;

    p_http1_session->i_flag_req_report_end = 1;

    return APM_L7_ANALYZE_SET_REQ(APM_L7_ANALYZE_SUCC);

ERROR:
    if(p_header_buff)
        frfree(p_header_buff);

    if(p_tmp)
        frfree(p_tmp);

    return APM_L7_ANALYZE_FAIL;
}


/*!
 * \brief HTTP/1.0短连接是 response数据上报
 *
 */

int http_resp_report(L7session_http_private *p_st_private, Frhash_header *p_st_hash_report)
{
    int i_ret = 0;
    Http1_session *p_http1_session = NULL;
    Http_comm_session *p_comm_session = NULL;
    L4_transaction *p_st_l4_trans = NULL;
    Frreport_data *p_st_report_data = NULL;
    Frbyte_Packet *p_packet = NULL, *p_st_rmi = NULL;
    unsigned long ul_tmp = 0;
    char *p_header_buff = NULL;
    unsigned int ui_header_buff_len = 0;
    char arr_head[256];
    char *p_header_buff_tmp = NULL, *p_chunk_data = NULL, *p_zdata = NULL;
    unsigned long ul_zdata_len = 0;

    if(p_st_private == NULL || p_st_private->p_http1_sess == NULL)
        return APM_L7_ANALYZE_FAIL;

    //body数据上报
    p_http1_session = p_st_private->p_http1_sess;
    p_comm_session = p_http1_session->p_st_comm_session;
    if(p_comm_session == NULL)
        return APM_L7_ANALYZE_FAIL;

    p_st_l4_trans = &p_comm_session->st_l4_trans;

    if(p_comm_session->p_st_body_data_resp == NULL)
        return APM_L7_ANALYZE_FAIL;

    //数据处理
    if(p_comm_session->i_flag_need == 1)
    {
        //chunk 反解析
        if(p_comm_session->i_flag_chunk)
        {
            //chunk解析
            i_ret = de_chunked((unsigned char *)p_header_buff, ui_header_buff_len, &p_chunk_data, &ul_zdata_len);
            frfree(p_header_buff);
            if(i_ret == -1)
                return APM_L7_ANALYZE_FAIL;

            if(i_ret == 0)
                return APM_L7_ANALYZE_TODO;
            
            if(p_comm_session->i_flag_data_type == HTTP_RMI_DATA
               || p_comm_session->i_flag_data_type == HTTP_YONGYOU_DATA)
            {
                p_st_rmi = bytebuff_creat();
                if(p_st_rmi == NULL)
                    return APM_L7_ANALYZE_FAIL;
    
                i_ret = bytebuff_add(p_st_rmi, p_chunk_data, ul_zdata_len);
                frfree(p_chunk_data);
                if(i_ret == FR_FAIL)
                    return APM_L7_ANALYZE_FAIL;
    
                //如果是rmi yongyou的数据 直接传bytebuffer 解析
                i_ret = frhttp_extend_bodydata_deal(p_st_rmi, p_comm_session, p_comm_session->p_st_body_data_resp, FR_NO);
                bytebuff_free(&p_st_rmi);
                if(i_ret == HTTP_EXTEND_DONE_SUCC)
                    return APM_L7_ANALYZE_SUCC;
                else if(i_ret == HTTP_EXTEND_DONE_FAIL)
                    return APM_L7_ANALYZE_FAIL;
    
                return APM_L7_ANALYZE_SUCC;
    
            }

            p_header_buff = p_chunk_data;
            p_chunk_data = NULL;
            ui_header_buff_len = ul_zdata_len;
        }
        else
        {
            //如果是rmi yongyou的数据 直接传bytebuffer 解析
            i_ret = frhttp_extend_bodydata_deal(p_packet, p_comm_session, p_comm_session->p_st_body_data_resp, FR_NO);
            if(i_ret == HTTP_EXTEND_DONE_SUCC)
                return APM_L7_ANALYZE_SUCC;
            else if(i_ret == HTTP_EXTEND_DONE_FAIL)
                return APM_L7_ANALYZE_FAIL;
    
            //如果不是RMI 取出内容继续解析
            ui_header_buff_len = (unsigned int)bytebuff_length(p_packet);
            //获取整个数据块
            p_header_buff = (char *)frmalloc(ui_header_buff_len + 1);
            if(p_header_buff == NULL)
                return APM_L7_ANALYZE_FAIL;
            i_ret = bytebuff_peek_bytes(p_packet, p_header_buff, ui_header_buff_len);
            if(i_ret == FR_FAIL)
            {
                frfree(p_header_buff);
                return APM_L7_ANALYZE_FAIL;
            }
            p_header_buff[ui_header_buff_len] = '\0';
    
            //body数据存入内存块 释放bytebuffer
            bytebuff_free(&p_comm_session->p_st_data);
        }

        //multipart
        if(p_comm_session->i_flag_multipart)
        {
            i_ret = multipart_data_parse(p_header_buff, ui_header_buff_len, p_comm_session->p_st_body_data_resp, p_st_private, FR_NO);
            frfree(p_header_buff);
            return i_ret;
        }
        //gizp解压
        if(p_comm_session->i_flag_gzip)
        {
            i_ret = frgzip_decompress((Byte *)p_header_buff, ui_header_buff_len, &p_zdata, &ul_zdata_len);
            frfree(p_header_buff);
            if(i_ret != FR_SUCC)
            {
                if(p_zdata)
                    frfree(p_zdata);

                return APM_L7_ANALYZE_FAIL;
            }

        }
        else if(p_comm_session->i_flag_deflate)
        {
            //不用解压
            p_header_buff_tmp = (char *)frmalloc(ui_header_buff_len + 10);
            memcpy(p_header_buff_tmp,"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00",10);
            memcpy(p_header_buff_tmp + 10,p_header_buff,ui_header_buff_len);
            ui_header_buff_len += 10;
            frfree(p_header_buff);
            p_header_buff = p_header_buff_tmp;

            i_ret = frgzip_decompress((Byte *)p_header_buff, ui_header_buff_len, &p_zdata, &ul_zdata_len);
            frfree(p_header_buff);
            if(i_ret != FR_SUCC)
            {
                if(p_zdata)
                    frfree(p_zdata);

                return APM_L7_ANALYZE_FAIL;
            }
        }
        else
        {
            //不用解压
            p_zdata = p_header_buff;
            ul_zdata_len = ui_header_buff_len;
        }

        if(p_comm_session->i_flag_need != 2 && p_comm_session->arr_charset[0]!= '\0'
           && (strcasecmp(p_comm_session->arr_charset, "utf-8") != 0 && strcasecmp(p_comm_session->arr_charset, "utf8") != 0))
        {
            p_header_buff = NULL;
            i_ret = iconv_to_utf8(p_zdata, ul_zdata_len, p_comm_session->arr_charset, &p_header_buff, &ui_header_buff_len);
            if(i_ret != 0)
            {
                if(p_zdata)
                    frfree(p_zdata);

                if(p_header_buff)
                    frfree(p_header_buff);

                return APM_L7_ANALYZE_FAIL;
            }

            frfree(p_zdata);
            p_zdata = p_header_buff;
            ul_zdata_len = ui_header_buff_len;
        }

        //如果不是chunk格式则存在p_st_private->i_data_len
        if(p_comm_session->i_flag_data_type == HTTP_XML_DATA)
        {
            i_ret = frsoap_parse_resp(p_zdata, ul_zdata_len, p_comm_session->p_st_body_data_resp, &p_comm_session->p_code_string, &p_comm_session->p_err_msg);
            if(i_ret == FR_FAIL)
            {
                frfree(p_zdata);
                return APM_L7_ANALYZE_FAIL;
            }

            //字段名
            snprintf(arr_head, sizeof(arr_head), "response.http.body.%d", 1);
            i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, arr_head, p_zdata);
            if(i_ret == FR_FAIL)
            {
                frfree(p_zdata);
                return APM_L7_ANALYZE_FAIL;
            }
            p_comm_session->p_xml_data = frstrdup(p_zdata);
            if(p_comm_session->p_xml_data == NULL)
            {
                frfree(p_zdata);
                return APM_L7_ANALYZE_FAIL;
            }

                #ifdef FRDBG_XML_DATA_OUTPUT
                FILE *fp_xml_data = NULL;
            struct timeval st_time;
            char arr_tmp[128];

            gettimeofday (&st_time, NULL);
            snprintf(arr_tmp, sizeof(arr_tmp), "%d%d.txt", st_time.tv_sec, st_time.tv_usec);
            fp_xml_data = fopen(arr_tmp,"w");
            if(fp_xml_data)
            {
                fprintf(fp_xml_data, "%s\n", p_zdata);
                fclose(fp_xml_data);
            }
                #endif
            frfree(p_zdata);
        }
        else if(p_comm_session->i_flag_data_type == HTTP_JSON_DATA)
        {
            //字段名
            snprintf(arr_head, sizeof(arr_head), "response.http.body.%d", 1);
            i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, arr_head, p_zdata);
            if(i_ret == FR_FAIL)
            {
                frfree(p_zdata);
                return APM_L7_ANALYZE_FAIL;
            }
            frfree(p_zdata);
        }
        else
            frfree(p_zdata);

        return APM_L7_ANALYZE_SUCC;

    }
    else
    {
        bytebuff_free(&p_comm_session->p_st_data);
    }

    p_http1_session->i_flag_resp_finish = 0;

    //comm信息
    if(p_st_l4_trans->st_request_time_first_byte.tv_sec)
    {
        //comm
        if(FRREPORT_BODY_L7LIST_SET_COMM(p_comm_session->p_st_body_data_resp, &p_comm_session->p_lst_comm_tmp) == FR_FAIL)
            goto ERROR;

        //把req数据链表添加到resp中
        if(FRREPORT_BODY_L7LIST_SET_REQ(p_comm_session->p_st_body_data_resp, &p_comm_session->p_lst_req_tmp) == FR_FAIL)
            goto ERROR;

        //server_time_us
        ul_tmp = (unsigned long)frtime_diff(&p_st_l4_trans->st_request_time, &p_st_l4_trans->st_response_time_first_byte);
        if(frreport_body_l7_add_ulong(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_SERVER_TIME_US, ul_tmp) == FR_FAIL)
            goto ERROR;
    }
    else
    {
        return APM_L7_ANALYZE_FAIL;
    }

    if(frreport_body_l7_add_long(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_DATA_BYTES, p_st_l4_trans->l_response_bytes) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_timeval(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_END_TIMESTAMP, &p_st_l4_trans->st_response_time) == FR_FAIL)
        goto ERROR;

    ul_tmp = (unsigned long)frtime_diff(&p_st_l4_trans->st_response_time_first_byte, &p_st_l4_trans->st_response_time);
    if(frreport_body_l7_add_ulong(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_DOWNLOAD_TIME_US, ul_tmp) == FR_FAIL)
        goto ERROR;


    p_st_l4_trans->ul_response_time_us = (unsigned long)frtime_diff(&(p_st_l4_trans->st_request_time_first_byte), &p_st_l4_trans->st_response_time);

    if(p_comm_session->p_err_msg)
    {
        //err message 上报
        i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_ERR_MSG, p_comm_session->p_err_msg);
        if(i_ret == FR_FAIL)
            goto ERROR;

        //resp code 上报
        i_ret = frreport_body_l7_add_long(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_CODE, 500);
        if(i_ret == FR_FAIL)
            goto ERROR;
    }
    else
    {
        //resp code 上报
        i_ret = frreport_body_l7_add_long(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_CODE, p_comm_session->l_response_code);
        if(i_ret == FR_FAIL)
            goto ERROR;
    }

    //resp code string 上报
    i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_CODE_STRING, p_comm_session->p_code_string);
    if(i_ret == FR_FAIL)
        goto ERROR;

    if(p_comm_session->p_err_msg == NULL)
    {
        i_ret = frreport_body_l7_add_str(p_comm_session->p_st_body_data_resp, APM_REPORT_KEY_RESP_ERR_MSG, p_comm_session->p_code_string);
        if(i_ret == FR_FAIL)
            goto ERROR;
    }


    if(p_st_l4_trans->st_request_time_first_byte.tv_sec == 0)
        p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_REQ);
    else
        p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_RESP);
    if(p_st_report_data == NULL)
        goto ERROR;

    //resp 数据上报
    if(frreport_data_add_body(p_st_report_data, p_comm_session->p_st_body_data_resp) == FR_FAIL)
        goto ERROR;
    p_comm_session->p_st_body_data_resp = NULL;

    if(frreport_data_hash(p_st_hash_report, p_st_report_data) == FR_FAIL)
        goto ERROR;

    return APM_L7_ANALYZE_SET_RESP(APM_L7_ANALYZE_SUCC);


    if(i_ret == APM_L7_ANALYZE_FAIL)
        goto ERROR;

    return i_ret;

    ERROR:

    if(p_st_report_data)
        frreport_data_free(&p_st_report_data);

    return APM_L7_ANALYZE_FAIL;
}
